'''
单词翻译模块，将英文单词查询出中文释义
'''

import re
import aiohttp
import asyncio
import bs4
from bs4 import BeautifulSoup


from datastore import datastore
from log import log
import settings
from model.models import modelWordCount
import statistics

logging = log(filename=settings.WORDTRANS_LOG_FILE, level=log.INFO)

class wordTranslate:
    '''
    单词翻译模块，目前使用有道翻译
    '''
    BASE_URL = r'http://dict.youdao.com/w/eng/' #基础URL
    SUFFIX_URL = r'/#keyfrom=dict.index' #URL后缀
    SCHEMA_SOUNDMARK = '.pronounce .phonetic' #音标的匹配字符串
    SCHEMA_TRANS = '.trans-wrapper .trans-container ul' #翻译的匹配字符串
    SLEEP_TIME = 10 #无单词需要翻译时，等待时间
    CYCLE_GAP = 0.2 #翻译任务循环调度间隔

    def __init__(self):
        self.logging = logging
        self.datastore = datastore()

    async def downloadHtml(self, session, url):
        '''
        下载url
        '''
        self.logging.info('download Html url = {}'.format(url))
        async with session.get(url) as resp:
            return await resp.read()

    async def search(self, word) -> modelWordCount:
        '''
        单词查询
        '''        
        English = None
        American = None
        trans = None
        
        async with aiohttp.ClientSession() as session:
            html = await self.downloadHtml(session, wordTranslate.BASE_URL + word + wordTranslate.SUFFIX_URL)

        soup = BeautifulSoup(html, features='lxml')                
        res = soup.select(wordTranslate.SCHEMA_SOUNDMARK)
        try:
            if res:
                if len(res) == 2:
                    English = res[0].contents[0] #英音音标
                    American = res[1].contents[0] #美音音标
                else:
                    English = American = res[0].contents[0]
            else:
                self.logging.warning('no result word={}'.format(word))
            res = soup.select(wordTranslate.SCHEMA_TRANS)
            if American or English:
                trans = (''.join(res[0].strings)).replace('\n', ' ')
                trans = '英：{}，美：{}，{}'.format(English, American, trans)
        except Exception as e:
            self.logging.error('search word exceptions {}'.format(e))

        return trans
        
    async def start(self):
        '''
        单词翻译启动函数
        '''
        try:                    
            while True:
                word = self.datastore.topUntranslateWord()
                if not word:
                    self.logging.warning('no words')
                    await asyncio.sleep(wordTranslate.SLEEP_TIME)
                    continue
                trans = await self.search(word)
                if trans:                    
                    self.datastore.updateWordTrans(word, trans)

                statistics.addTransNum(1)                
                await asyncio.sleep(wordTranslate.CYCLE_GAP)        
        except Exception as e:
            self.logging.info('except {}'.format(e))

def main():
    tran = wordTranslate()
    res = asyncio.run(tran.search('leftmost'))

    print(res)

if __name__ == '__main__':
    main()
